Hellforge General Crackme III
by LazaRuS
Tutorial de Lucifer48 [Immortal Descendants]
(13 ao√t 1999)
Le crackme est programmΘ en C++ builder, en gros τa ressemble α du delphi (je me demande lequel
des deux est le pire ?). Le code est assez polluΘ, mais l'algorithme est ultra simple.
Un bpx hmemcpy nous permet d'entrer dans le code:
XXXX:004028ED CALL 004273E4 ;rΘsultat: eax=longueur du nom (on sort d'ici)
XXXX:004028F2 LEA EAX,[EBP-01DC]
XXXX:004028F8 CALL 0044DE94
XXXX:004028FD INC EAX ;longueur du nom +1
XXXX:004028FE CMP EDI,EAX ;edi est l'indice de boucle
XXXX:00402900 LEA EAX,[EBP-01DC]
XXXX:00402906 SETL DL
XXXX:00402909 AND EDX,01
XXXX:0040290C PUSH EDX ;EDX=0 ou EDX=1
...
XXXX:0040291A POP ECX
XXXX:0040291B TEST ECX,ECX ;si ECX=0, c'est la fin de la boucle
XXXX:0040291D JNZ 0040285D ;retour dΘbut de la boucle
On voit qu'on attΘrit dans une boucle. Mais que fait cette (Θnorme) boucle ? En fait c'est trΦs
simple, elle additionne seulement chaque valeur ascii des caractΦres du nom:
XXXX:004028A6 MOV EDX,[EBP-0234] ;indice de boucle
XXXX:004028AC ADD EDX,[EBP-01E0] ;ajoute l'adresse du nom
XXXX:00402AB2 DEC EDX
XXXX:00402AB3 MOVSX ECX,BYTE PTR [EDX] ;lit l'un des caractΦres du nom
XXXX:00402AB6 ADD [EBP-0230],ECX ;grosse addition
Exemple: Pour mon nom (Lucifer48), j'obtient:
4C + 75 + 63 + 69 + 66 + 65 + 72 + 34 + 38 = 336h
Juste aprΦs la boucle:
XXXX:00402923 IMUL EAX,[EBP-0230],000A2D77
XXXX:0040292D MOV [EBP-230],EAX ;sauvegarde pour la comparaison finale
On continue:
XXXX:004029A5 CMP EDI,EAX ;taille des deux serials
XXXX:004029A7 LEA EAX,[EBP-01E8] ; edi: taille du premier serial
XXXX:004029AD SETZ DL ; eax: taille du second serial
XXXX:004029B0 AND EDX,01
XXXX:004029B3 PUSH EDX
...
XXXX:004029D4 POP ECX
XXXX:004029D5 TEST CL,CL
XXXX:004029D7 JZ 00402B9C ;jump = les deux serials n'ont pas la mΩme taille
Donc pour pouvoir continuer, il faut que les deux serials soient de mΩme longueur. On arrive
maintenant α la boucle des serials; lα encore, elle est Θnorme, mais en fait ce qu'elle fait
est trΦs simple:
XXXX:00402A41 MOV EDX,[EBP-023C] ;indice de boucle (k)
XXXX:00402A47 XOR EAX,EAX
XXXX:00402A49 ADD EDX,[EBP-01F0] ;adresse du premier serial
XXXX:00402A4F DEC EDX
XXXX:00402A50 MOV CL,[EDX] ;lit le k-iΦme caractΦre du serial1
...
XXXX:00402A9A MOV EDX,[EBP-0240] ;indice de boucle (k)
XXXX:00402AA0 POP EAX ;AL= k-iΦme caractΦre du serial1
XXXX:00402AA1 ADD EDX,[EBP-01F4] ;adresse du second serial
XXXX:00402AA7 MOV ECX,0000000A
XXXX:00402AAC DEC EDX
XXXX:00402AAD XOR AL,[EDX] ;xor avec le k-iΦme caractΦre du serial2
XXXX:00402AAF MOVSX EAX,AL
XXXX:00402AB2 CDQ
XXXX:00402AB3 IDIV ECX
XXXX:00402AB5 MOVSX EDX,DL ;instruction inutile ici
...
XXXX:00402B93 POP ECX ;ecx=0 ou ecx=1
XXXX:00402B94 TEST ECX,ECX
XXXX:00402B96 JNZ 004029F2 ;si ecx=1 alors la boucle n'est pas finie
Ansi chaque reste de la division euclidienne va Ωtre gardΘ et mis bout α bout (via une procΘdure
similaire α wfprintf). On arrive maintenant α la comparaison finale:
XXXX:00402BBF LEA EDX,[EBP-0200] ;d *edx: rΘsultat du nom (ce qu'il faut trouver)
XXXX:00402BC5 LEA EAX,[EBP-10] ;d *eax: code issu des modulos (serial)
XXXX:00402BC8 CALL 0044DE7C ;comparaison
XXXX:00402BCD PUSH EAX
...
XXXX:00402BE1 POP ECX
XXXX:00402BE2 TEST CL,CL
XXXX:00402BE4 JZ 00402C14 ;jmp = mauvais serials
Voilα la registration la plus facile (pour moi):
Name/ Lucifer48
Serial/ 548273178
Serial/ 000000000
ou
Serial/ 548273179
Serial/ 000000001
...
Serial/ <=1;>:8>1
Serial/ 999999999
Prendre des chiffres est la faτon la plus simple, car on ne se soucit pas de la division
euclidienne. Une derniΦre...
Name/ Lucifer48
Serial/ Lucifer48
Serial/ 15E516530
C'est fini !
Greetings: All ID members (Volatility, Torn@do, ...), Eternal Bliss, ACiD BuRN,
Duelist, LaZaRuS, people on #cracking4newbies, french crackers, and other crackme makers.
(c) Lucifer48. All rights reversed